﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jizsoft.JFrame.Identity.Domain.Strategies
{
    /// <summary>
    /// 密码安全保护策略
    /// </summary>
    public class CryptoSecurityStrategy : ICryptoSecurityStrategy
    {
        /// <summary>
        /// 错误密码
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public LockResult IncorrectPassword(JFDbContext dbContext, Entities.User user)
        {
            LockResult result = new LockResult();
            if (user.Status == Constant.UserStatus.Locked)
            {
                // 密码错误,账号并且已被锁定，密码保护策略执行操作
                // 更新账号锁定时间
                user.UnlockTime = DateTime.Now.AddMinutes(30);
                dbContext.Entry<Entities.User>(user).State = System.Data.Entity.EntityState.Modified;

                result.IsLocked = true;
                result.RetryCount = 0;
                result.LockoutDuration = 30;
            }
            else
            {
                // 密码错误, 账号未被锁定，密码保护策略执行操作
                List<Entities.IllegalPassword> lst = dbContext.Set<Entities.IllegalPassword>().Where(p => p.UserId == user.Id && p.IsValid).ToList();
                if (lst.Count >= 4)
                {
                    // 创建一个错误记录
                    Entities.IllegalPassword record = new Entities.IllegalPassword();
                    record.Id = Guid.NewGuid();
                    record.IsValid = true;
                    record.OccurredTime = DateTime.Now;
                    record.UserId = user.Id;
                    dbContext.Set <Entities.IllegalPassword>().Add(record);

                    // 锁定账号
                    user.Status = Constant.UserStatus.Locked;
                    user.UnlockTime = DateTime.Now.AddMinutes(30);
                    dbContext.Entry<Entities.User>(user).State = System.Data.Entity.EntityState.Modified;

                    result.IsLocked = true;
                    result.RetryCount = 0;
                    result.LockoutDuration = 30;
                }
                else
                {
                    // 创建一个错误记录
                    Entities.IllegalPassword record = new Entities.IllegalPassword();
                    record.Id = Guid.NewGuid();
                    record.IsValid = true;
                    record.OccurredTime = DateTime.Now;
                    record.UserId = user.Id;
                    dbContext.Set<Entities.IllegalPassword>().Add(record);

                    result.IsLocked = false;
                    result.RetryCount = 5 - lst.Count - 1;
                }
            }
            return result;
        }

        /// <summary>
        /// 输入正确密码
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public LockResult CorrectPassword(JFDbContext dbContext, Entities.User user)
        {
            LockResult result = new LockResult();

            // 去除非法密码记录
            List<Entities.IllegalPassword> list = dbContext.Set<Entities.IllegalPassword>().Where(p => p.UserId == user.Id && p.IsValid).ToList();
            for (int index = 0; index < list.Count; index++)
            {
                list[index].IsValid = false;
                dbContext.Entry<Entities.IllegalPassword>(list[index]).State = System.Data.Entity.EntityState.Modified;
            }

            // 解锁账号
            user.Status = Constant.UserStatus.Normal; ;
            user.UnlockTime = null;
            dbContext.Entry<Entities.User>(user).State = System.Data.Entity.EntityState.Modified;

            result.IsLocked = false;
            result.RetryCount = 0;
            result.LockoutDuration = 0;

            return result;
        }
    }
}
